using JT808Protocol.Common;
using JT808Protocol.Models.BodyParserStrategy.Location.LocationAddition;
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;

namespace JT808Protocol.Models.BodyParserStrategy.Location
{
    public class DrLocation_0x0200 : IJT808Body
    {
        /// <summary>
        /// 报警标志位
        /// </summary>
        [JsonPropertyName("报警标志位")]
        public AlarmStatusBits AlarmStatusBits { get; set; }

        /// <summary>
        /// 设备状态位
        /// </summary>
        [JsonPropertyName("设备状态位")]
        public DeviceStatusBits DeviceStatusBits { get; set; }

        /// <summary>
        /// 纬度
        /// </summary>
        [JsonPropertyName("纬度")] public decimal Latitude { get; set; }

        /// <summary>
        /// 经度
        /// </summary>
        [JsonPropertyName("经度")] public decimal Longtitude { get; set; }

        /// <summary>
        /// 高程
        /// </summary>
        [JsonPropertyName("高程")] public decimal Altitude { get; set; }

        /// <summary>
        /// 速度
        /// </summary>
        [JsonPropertyName("速度")] public decimal Speed { get; set; }

        /// <summary>
        /// 方向
        /// </summary>
        [JsonPropertyName("方向")] public decimal Direction { get; set; }

        /// <summary>
        /// 时间
        /// </summary>
        [JsonPropertyName("时间")] public DateTime Time { get; set; }

        /// <summary>
        /// 位置附加信息
        /// </summary>
        [JsonPropertyName("位置附加信息")] public List<ILocationAddition> Additions { get; set; }

        /// <summary>
        /// 解析消息体
        /// </summary>
        /// <param name="data"></param>
        /// <param name="index"></param>
        /// <param name="Length">长度</param>
        /// <returns></returns>
        public IJT808Body ReadBody(ReadOnlySpan<byte> data, int index, int Length)
        {
            var alarmStatus = ParseHelper.Uint32(ref data, index);
            //解析报警标志
            AlarmStatusBits = new AlarmStatusBits();
            AlarmStatusBits.ReadStatus(alarmStatus);
            index += 4;

            var deviceStatus = ParseHelper.Uint32(ref data, index);
            //解析设备状态
            DeviceStatusBits = new DeviceStatusBits();
            DeviceStatusBits.ReadStatus(deviceStatus);
            index += 4;

            Latitude = ParseHelper.Uint32(ref data, index);
            index += 4;
            Longtitude = ParseHelper.Uint32(ref data, index);
            index += 4;
            Altitude = ParseHelper.Uint16(ref data, index);
            index += 2;
            Speed = ParseHelper.Uint16(ref data, index);
            index += 2;
            Direction = ParseHelper.Uint16(ref data, index);
            index += 2;
            Time = ParseHelper.BcdTo1078Datetime(ref data, index);
            index += 6;

            //解析位置附加信息
            Additions = new List<ILocationAddition>();
            while (index < Length)
            {
                int addiId = Convert.ToInt32(data[index]);
                ILocationAddition addi = JT808MsgBodyParserFactory.GetLocationAddtionParser((EnumLocationAddition)addiId);

                if (addi != null)
                {
                    //主动安全报警类型
                    if (addi.AdditionID == EnumLocationAddition.ADAS ||
                        addi.AdditionID == EnumLocationAddition.BSD ||
                        addi.AdditionID == EnumLocationAddition.DSM ||
                        addi.AdditionID == EnumLocationAddition.TPMS)
                    {
                        if (HeaderContext.ProtocolVersion == JT808ProtocolVersion.v2019)
                        {
                            //粤标在2019基础上新增主动安全
                            addi.AlarmLogo = new LaAlarmLogo_Yue();
                            Array.Copy(data.ToArray(), index, addi.AlarmLogo.OriginalData, 0, 40);
                        }
                        else if (HeaderContext.ProtocolVersion == JT808ProtocolVersion.v2013)
                        {
                            //苏标在2013基础上新增主动安全
                            addi.AlarmLogo = new LaAlarmLogo_Su();
                            Array.Copy(data.ToArray(), index, addi.AlarmLogo.OriginalData, 0, 16);
                        }
                    }

                    addi.ReadEntity(data, index);
                    Additions.Add(addi);

                    index += addi.DataLength;
                }
                else
                {
                    //Logger.Error($"位置附加信息类型:{addiId.ToString("X2")找不到解析器}");
                    //跳过解析下一个
                    index += data[index + 1] + 2;
                }
            }

            return this;
        }

        /// <summary>
        /// 解析消息体
        /// </summary>
        /// <param name="data"></param>
        /// <param name="index"></param>
        /// <returns></returns>
        public override IJT808Body ReadBody(ReadOnlySpan<byte> data, ref int index)
        {
            var alarmStatus = ParseHelper.Uint32(ref data, index);
            //解析报警标志
            AlarmStatusBits = new AlarmStatusBits();
            AlarmStatusBits.ReadStatus(alarmStatus);
            index += 4;

            var deviceStatus = ParseHelper.Uint32(ref data, index);
            //解析设备状态
            DeviceStatusBits = new DeviceStatusBits();
            DeviceStatusBits.ReadStatus(deviceStatus);
            index += 4;

            Latitude = ParseHelper.Uint32(ref data, index);
            index += 4;
            Longtitude = ParseHelper.Uint32(ref data, index);
            index += 4;
            Altitude = ParseHelper.Uint16(ref data, index);
            index += 2;
            Speed = ParseHelper.Uint16(ref data, index);
            index += 2;
            Direction = ParseHelper.Uint16(ref data, index);
            index += 2;
            Time = ParseHelper.BcdTo1078Datetime(ref data, index);
            index += 6;

            //解析位置附加信息
            Additions = new List<ILocationAddition>();
            while (index < data.Length - 2)
            {
                int addiId = Convert.ToInt32(data[index]);
                ILocationAddition addi = JT808MsgBodyParserFactory.GetLocationAddtionParser((EnumLocationAddition)addiId);

                if (addi != null)
                {
                    //主动安全报警类型
                    if (addi.AdditionID == EnumLocationAddition.ADAS ||
                        addi.AdditionID == EnumLocationAddition.BSD ||
                        addi.AdditionID == EnumLocationAddition.DSM ||
                        addi.AdditionID == EnumLocationAddition.TPMS)
                    {
                        if (HeaderContext.ProtocolVersion == JT808ProtocolVersion.v2019)
                        {
                            //粤标在2019基础上新增主动安全
                            addi.AlarmLogo = new LaAlarmLogo_Yue();
                            Array.Copy(data.ToArray(), index, addi.AlarmLogo.OriginalData, 0, 40);
                        }
                        else if (HeaderContext.ProtocolVersion == JT808ProtocolVersion.v2013)
                        {
                            //苏标在2013基础上新增主动安全
                            addi.AlarmLogo = new LaAlarmLogo_Su();
                            Array.Copy(data.ToArray(), index, addi.AlarmLogo.OriginalData, 0, 16);
                        }
                    }

                    addi.ReadEntity(data, index);
                    Additions.Add(addi);

                    index += addi.DataLength;
                }
                else
                {
                    //Logger.Error($"位置附加信息类型:{addiId.ToString("X2")找不到解析器}");
                    //跳过解析下一个
                    index += data[index + 1] + 2;
                }
            }

            return this;
        }

        public override List<byte> WriteToBytes()
        {
            throw new NotImplementedException();
        }
    }
}